
package com.vanda.db.tag;

import java.util.ArrayList;
import java.util.HashMap;

import org.apache.commons.beanutils.PropertyUtils;

import com.vanda.db.XQLData;
import com.vanda.db.convert.Convert;
import com.vanda.db.convert.ConvertFactory;
import com.vanda.db.util.XMLParser;

/**
 * 所有标签类的父类<br>
 * 
 * @author 王瑛<br>
 * @version Version 1.00<br>
 */
public abstract class Tag {
	/** 标签头定义 */
	public static final String TAG_HEAD="<logic:";
	/** 标签尾定义 */
	public static final String TAG_TAIL="</logic:";
	/** 属性标签定义 */
	public static final String[] PROPERTY_FLAG = {"[","]"};
	/** 非空标签定义 */
	public static final String[] EMPTY_FLAG = {"{","}"};

	/**
	 * 标签包含的内容，不包括标签本身，例如<empty property="a.b">table.field = {a.b}</empty>，
	 * 那么对应的content=table.field = {a.b}
	 */
	private String content;
	
	/** 传入参数,key=别名，value=别名对应的实例（不是class名） */
	private HashMap params;
	
	
	/**
	 * 解析标签内容，需要处理嵌套标签
	 * @return 解析后的xql及参数
	 */
	public XQLData parse() throws Exception{
		XQLData data = new XQLData("",new ArrayList());
		
		String[] parts = XMLParser.parse(content);
		for(int i=0;i<parts.length;i++){
			//如果不是标签
			if(parts[i].indexOf(TAG_HEAD) < 0){
				XQLData childData = parse(parts[i]);
				data.add(childData);
			}else{
				//如果是标签，取得标签头
				String head = XMLParser.getTagHead(parts[i]);
				//根据标签头生成对应标签实例
				Tag childTag = TagFactory.getInstance(head);
				childTag.setContent(XMLParser.getTagContent(parts[i]));
				childTag.setParams(params);
				
				//如果条件是真，则解析标签内容
				if(childTag.condition()){
					XQLData childData = childTag.parse();
					data.add(childData);
				}

			}
		}
		
		return data;
	}
	
	/**
	 * 解析xql内容，里面不包含标签
	 * @param xql 
	 * @return
	 */
	private XQLData parse(String xql) throws Exception{
		XQLData data = new XQLData("",new ArrayList());
		
		int index = xql.indexOf(PROPERTY_FLAG[0]);
		while (index >= 0) {
			data.setXql(data.getXql()+xql.substring(0, index));
			int end = xql.indexOf(PROPERTY_FLAG[1]);
			if (end == -1) {
				throw new Exception("no } !");
			}
			String property = xql.substring(index + 1, end);
			
			Convert dialect = ConvertFactory.getInstance(property,params);
			XQLData childData = dialect.parse();
			
			data.add(childData);
			
			xql = xql.substring(end + 1, xql.length());
			index = xql.indexOf(PROPERTY_FLAG[0]);
		}
		
		data.setXql(data.getXql()+xql);
		
		
		
		return data;
	}
	
	/**
	 * 返回比较结果
	 * @return true-条件真,false-条件假
	 */
	public abstract boolean condition();
	
	/**
	 * 取得property对应的值
	 * 例如：a.field
	 * @param property 属性值
	 * @return 
	 */
	protected Object getValue(String property) throws Exception{
		//取得property的前缀和后缀
		property = property.trim();
		int index = property.indexOf(".");
		if (index == -1) {
			return property;
		}
		String paramName = property.substring(0, index);
		property = property.substring(index + 1, property.length());
		
		//取得paramName对应的实例
		Object obj = params.get(paramName);
		if(obj == null){
			return property;
		}
		
		Object objParam = PropertyUtils.getProperty(obj, property);
		return objParam;
	}

	public HashMap getParams() {
		return params;
	}

	public void setParams(HashMap map) {
		params = map;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String string) {
		content = string;
	}

}
